package game;

import game.entities.Archer;
import game.entities.Player;
import game.entities.PodGuy;
import game.entities.Rogue;
import game.entities.Swordsman;
import game.gfx.Colors;
import game.gfx.Screen;
import game.gfx.SpriteSheet;
import game.level.Level;
import game.Log;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Game extends Canvas implements Runnable {

	private static final long serialVersionUID = 1L;

	public static final int BASE_LENGTH = 640;
	public static final int SCALE = 2;
	public static final int WIDTH = BASE_LENGTH / SCALE;
	public static final int HEIGHT = WIDTH / 12 * 9;
	public static final String NAME = "Game";
	public static Game game;

	public JFrame frame;
	public boolean running = false;
	public int tickCount = 0;

	public String[] classes = { "swordsman", "archer", "pod guy" };

	private BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
			BufferedImage.TYPE_INT_RGB);
	private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer())
			.getData();
	private int[] colors = new int[6 * 6 * 6];

	private Screen screen;
	public InputHandler input;
	public WindowHandler windowHandler;
	public Level level;
	public Rogue rogue;
	public Archer archer;
	public Swordsman swordsman;
	public PodGuy podguy;
	public Player player;
	public String puname;

	public Game() {
		setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

		frame = new JFrame(NAME);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new BorderLayout());

		frame.add(this, BorderLayout.CENTER);
		frame.pack();

		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public void init() {
		System.out.println("SDF");
		game = this;
		int index = 0;
		for (int r = 0; r < 6; r++) {
			for (int g = 0; g < 6; g++) {
				for (int b = 0; b < 6; b++) {
					int rr = (r * 255 / 5);
					int gg = (g * 255 / 5);
					int bb = (b * 255 / 5);

					colors[index++] = rr << 16 | gg << 8 | bb;
				}
			}
		}

		String classChoice = "";

		screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
		input = new InputHandler(this);
		windowHandler = new WindowHandler(this);
		level = new Level("/levels/med_test_level.png");
		BufferedReader br;
		try {
			br = new BufferedReader(new FileReader(puname + ".txt"));
			br.readLine();
			classChoice = br.readLine();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// String username =
		// JOptionPane.showInputDialog(this,"Please enter a username.");
		// Swordsman player = new
		// Swordsman(level,10,100,input,JOptionPane.showInputDialog(this,"Please enter a username."),7);
		switch (classChoice.toLowerCase().charAt(0)) {
		case 'a':
			player = new Archer(level, 10, 100, input, puname, 7);
			break;
		case 's':
			player = new Swordsman(level, 10, 100, input, puname, 7);
			break;
		case 'p':
			player = new PodGuy(level, 10, 100, input, puname, 7);
			break;
		}
		rogue = new Rogue(level, 250, 100, 7, player);
		level.addEntity(player);
		level.addEntity(rogue);
	}

	public synchronized void start(String username) {
		running = true;
		puname = username;
		new Thread(this).start();

	}

	public synchronized void stop() {
		running = false;
	}

	public void run() {
		long lastTime = System.nanoTime();
		double nsPerTick = 1000000000D / 60D;

		int ticks = 0;
		int frames = 0;

		long lastTimer = System.currentTimeMillis();
		double delta = 0;

		init();

		while (running) {
			long now = System.nanoTime();
			delta += (now - lastTime) / nsPerTick;
			lastTime = now;
			boolean shouldRender = true;

			while (delta >= 1) {
				ticks++;
				tick();
				delta -= 1;
				shouldRender = true;
			}

			try {
				Thread.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (shouldRender) {
				frames++;
				render();
			}

			if (System.currentTimeMillis() - lastTimer >= 1000) {
				lastTimer += 1000;
				frame.setTitle(ticks + " ticks, " + frames + " frames");
				frames = 0;
				ticks = 0;
			}
		}
	}

	public void tick() {
		tickCount++;
		level.tick();
	}

	public void render() {
		BufferStrategy bs = getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			return;
		}
		int xOffset = player.x - screen.width / 2;
		int yOffset = player.y - screen.height / 2;
		level.renderTiles(screen, xOffset, yOffset);

		for (int x = 0; x < level.width; x++) {
			int color = Colors.get(-1, -1, -1, 000);
			if (x % 10 == 0 && x != 0) {
				color = Colors.get(-1, -1, -1, 500);
			}
			// Font.render(x%10+"", screen, x*8, 0, color);
		}

		level.renderEntities(screen);

		for (int y = 0; y < screen.height; y++) {
			for (int x = 0; x < screen.width; x++) {
				int colorCode = screen.pixels[x + y * screen.width];
				if (colorCode < 255)
					pixels[x + y * WIDTH] = colors[colorCode];
			}
		}
		Graphics g = bs.getDrawGraphics();
		g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
		g.dispose();
		bs.show();
	}

	public static void main(String[] args) {
		// new Game().start();
	}
}
